package com.longlong.pool;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

/**
 * 连接池
 *
 * @author longlong
 */
public class ConnectionPool {

    /**
     * 单例模式
     */
    private ConnectionPool() {
    }

    private static volatile ConnectionPool connectionPool;

    public static ConnectionPool getInstance() {
        if (connectionPool == null) {
            synchronized (ConnectionPool.class) {
                if (connectionPool == null) {
                    connectionPool = new ConnectionPool();
                }
            }
        }
        return connectionPool;
    }

    /**
     * 连接池中连接的默认数量
     */
    private static final int DEFAULT_CONNECTION = 10;

    /**
     * 连接池
     */
    private final List<MyConnection> connectionList = new ArrayList<>();


    {
        int count;
        String minCount = ConfigurationReader.getStringValue("minCount");
        if (minCount == null) {
            count = DEFAULT_CONNECTION;
        } else {
            count = Integer.parseInt(minCount);
        }
        for (int i = 1; i <= count; i++) {
            connectionList.add(new MyConnection());
        }
    }


    /**
     * 获取连接
     *
     * @return 连接
     */
    private synchronized MyConnection getMc() {
        MyConnection result = null;
        // 连接池中寻找空闲连接
        for (MyConnection mc : connectionList) {
            if (!mc.isUsed()) {
                mc.setUsed(true);
                result = mc;
                break;
            }
        }
        return result;
    }

    /**
     * 获取连接（等待机制）
     * 每隔 100ms 获取一次，默认最多等待 5s
     * 可通过配置文件配置 最多等待时间
     *
     * @return 连接
     */
    public MyConnection getMyConnection() {
        int count;
        String waitTime = ConfigurationReader.getStringValue("waitTime");
        if (waitTime == null) {
            count = 5 * 10;
        } else {
            count = Integer.parseInt(waitTime) * 10;
        }
        MyConnection result = this.getMc();
        int i = 0;
        // 每隔 100ms 获取一次
        while (result == null && i < count) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            result = this.getMc();
            i++;
        }
        // 超过等待时间 仍未获得连接
        if (result == null) {
            // 自定义异常
            throw new RuntimeException("获取连接超时");
        }
        return result;
    }

    public Connection getConnection() {
        return this.getMyConnection();
    }

}
